package com.songcha.sakura.download.m3u8

import android.os.Parcel
import android.os.Parcelable
import com.songcha.library_common.util.LogUtil
import com.songcha.sakura.download.*
import com.songcha.sakura.download.base.DownloadTask
import com.songcha.sakura.download.base.IDownloader
import com.songcha.sakura.download.base.TaskState
import com.songcha.sakura.util.FileUtil
import com.songcha.sakura.util.HttpUtil
import java.io.File
import java.lang.StringBuilder

class M3u8Downloader() : IDownloader {


    constructor(parcel: Parcel) : this() {
    }

    override fun download(task: DownloadTask, listener: IDownloaderListener, iDownloadManager: IDownloadManager) :Int {

        task as M3u8DownloadTask
        task.tId=Thread.currentThread().id
        //task.option as M3u8DownloadOption
        //task.option.setPath()

        iDownloadManager.putTask(task)

        val t=iDownloadManager.takeTask() as M3u8DownloadTask

        listener.onInitialize(t)
        iDownloadManager.onInitialze(t)

        t.option as M3u8DownloadOption
        val episodeFile=File(t.option.episodePath)
        val indexFile=File(t.option.m3u8IndexPath)

        //var downloadedTsCount=0
        t.currentTsCount=0

        //继续下载未下载完成部分
        if(episodeFile.exists() && episodeFile.isDirectory && indexFile.exists()){
            val files=episodeFile.listFiles()
            if(files!=null){
                for(i in files.indices){
                    if(files[i].name.endsWith(".ts")){
                        //downloadedTsCount++
                        t.currentTsCount++
                        t.currentSize+=files[i].length().toInt()
                    }

                }
            }
        }else{
            episodeFile.mkdir()
        }

        if( t.currentTsCount>0){
            //删除最后一个ts文件
            FileUtil.delete(t.option.episodePath+"/"+(--t.currentTsCount)+".ts")
        }

        var hasBandWidthUrl=false
        var isDirectTs=false


        try{

            var m3u8UrlNew=""
            var tsList=ArrayList<String>()

            if(t.currentTsCount==0) {

                var resolution=""
                var temp=""

                HttpUtil.getUrlContent(t.url) { line ->
                    if(line.startsWith("#")){
                        if(line.contains("BANDWIDTH=")) {
                            hasBandWidthUrl = true
                            if(line.contains("RESOLUTION=") && resolution.isEmpty()){
                                val resolutionIdx=line.indexOf("RESOLUTION=")
                                val endResolutionIndex=line.indexOf(",",resolutionIdx)
                                if(endResolutionIndex>-1)
                                    resolution=line.substring(resolutionIdx+"RESOLUTION=".length,endResolutionIndex)
                                else
                                    resolution=line.substring(resolutionIdx+"RESOLUTION=".length)

                                if(resolution.isNotEmpty()){
                                    LogUtil.log("分辨率",resolution)
                                    t.option.resolution=resolution
                                }
                            }
                        }
                        if(line.contains("#EXT-X-VERSION:")){
                            isDirectTs=true
                        }
                    }else{
                        if(temp.isEmpty())
                            temp = line
                    }

                }


                if(temp.isNotEmpty() && hasBandWidthUrl){
                    m3u8UrlNew = t.option.urlConverter!!.convert(t.url, temp!!)
                    LogUtil.log("m3u8UrlNew", m3u8UrlNew)
                    tsList=convertUrlTsContent(t,m3u8UrlNew,indexFile)

                }else if(temp.isNotEmpty() && isDirectTs){
                    m3u8UrlNew=t.url
                    LogUtil.log("无需重定向m3u8url")
                    tsList=convertUrlTsContent(t,m3u8UrlNew,indexFile)

                }else{
                    val e= M3u8IndexTsException()
                    t.state= TaskState.ERROR
                    listener.onError(t,e)
                    iDownloadManager.onError(t,e)
                    return -4
                }


            }else{
                m3u8UrlNew=FileUtil.readContent(t.option.urlPath).split("|")[1]
                //m3u8UrlNew=m3u8UrlNew.substring(0,m3u8UrlNew.length-1)

                FileUtil.readContent(indexFile.path){line ->
                    if(line.contains(".ts")){
                        tsList.add(line)
                    }

                }
            }

            if(tsList.size==0){
                t.state= TaskState.ERROR
                val e= M3u8IndexTsException()
                listener.onError(t,e)
                iDownloadManager.onError(t,e)
                return -6
            }

            val tsListNew=t.option.tsConverter!!.convert(m3u8UrlNew,tsList)

            t.totalTsCount=tsListNew.size

                //开始下载
            listener.onStart(t)
            iDownloadManager.onStart(t)

            var isStop=false
            for(i in t.currentTsCount until tsListNew.size){
                val dt=Thread.currentThread() as DownloadThread
                if(!dt.isRun){
                    isStop=true
                    break
                }

                val tsUrl=tsListNew[i]

                val tsPath="${t.option.episodePath}/$i.ts"
                //FileUtil.mkDir(comicPath)

                val tsFile=File(tsPath)

                //LogUtil.log(tsUrl)

                val size=FileUtil.saveNetFile(tsFile,tsUrl)
                //t.currentSize=i+1
                t.currentSize+=size
                t.currentTsCount=i+1
                t.setProgress()

                LogUtil.log(t.option.fileName,"$i.ts下载完成","${t.progress}%")

                listener.onUpdate(t)
            }

            if(!isStop){
                indexFile.delete()
                listener.onCompleted(t)
                iDownloadManager.onComplete(t)
            }else{
                t.state= TaskState.PAUSE
                listener.onPause(t)
                iDownloadManager.onPause(t)
            }

        } catch (e:InterruptedException){
            e.printStackTrace()
            //listener.onError(task,e)
            //iDownloadManager.error(task,e)

        } catch (e:Exception){
            e.printStackTrace()
            t.state= TaskState.ERROR
            listener.onError(t,e)
            iDownloadManager.onError(t,e)

        }

        return t.id
    }

    override fun validateUrl(url:String): Boolean {
        if((url.startsWith("http://") || url.startsWith("https://")) && url.contains(".m3u8")){
            return true
        }
        return false
    }

    private fun convertUrlTsContent(t: M3u8DownloadTask, m3u8UrlNew:String, indexFile:File):ArrayList<String>{
        val tsList=ArrayList<String>()

        t.option as M3u8DownloadOption
        //转换为本地ts路径
        var sbTsConvert = StringBuilder()
        var i = 0
        val tsContent = HttpUtil.getUrlContent(m3u8UrlNew) { line ->
            if (line.contains(".ts")) {
                tsList.add(line)
                if (t.currentTsCount == 0) {
                    sbTsConvert.append(t.option.episodePath + "/$i.ts")
                    sbTsConvert.append("\r\n")
                    i++
                }
            } else {
                if (t.currentTsCount == 0) {
                    sbTsConvert.append(line)
                    sbTsConvert.append("\r\n")
                }

            }
        }

        //.m3u8.index为原始索引文件，.m3u8为转换后的文件
        //File(option.filePath).createNewFile()
        if(tsList.size>0){
            FileUtil.writeStr(indexFile, tsContent)
            if (t.currentTsCount == 0) {
                FileUtil.writeStr(File(t.option.filePath), sbTsConvert.toString())
                var str=t.url+"|"+m3u8UrlNew+"|"+t.option.resolution
                //if(str.endsWith("\r\n")) str=str.substring(0,str.length-2)
                //else if(str.endsWith("\n")) str=str.substring(0,str.length-1)
                FileUtil.writeStr(File(t.option.urlPath),str)
            }
        }

        return tsList
    }

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        //super.writeToParcel(parcel, flags)
    }

    override fun describeContents(): Int {
        return 0
    }

    companion object CREATOR : Parcelable.Creator<M3u8Downloader> {
        override fun createFromParcel(parcel: Parcel): M3u8Downloader {
            return M3u8Downloader(parcel)
        }

        override fun newArray(size: Int): Array<M3u8Downloader?> {
            return arrayOfNulls(size)
        }
    }
}